/************************************************************************/
/* GUI                                                                  */
/************************************************************************/
#include "GUI/EntryScreen.h"

namespace TD_Core {

	/************************************************************************/
	/* Default definitions                                                  */
	/************************************************************************/
	const string EntryScreen::entryScreenBackground = "entryScreen.png";
	const Coord2D EntryScreen::iconStartingPos(0.32226*screenWidth, 0.57291*screenHeight);
	

	/************************************************************************/
	/* Private functions                                                    */
	/************************************************************************/
	void EntryScreen::processLogo(SDL_Surface *g_pSurface, unsigned int deltaTime) {
		
		m_pLacaLogo->render(g_pSurface, deltaTime);
		m_pFadescreen->render(g_pSurface, deltaTime);
		int ticks = m_logoTimer.getTicks();
		if(m_pFadescreen->isFadingIn() && m_pFadescreen->finishedFading()) {
			if(!m_playedIntroSound) {
				m_pLogoSound->playSound(false);
				m_playedIntroSound = true;
			}
		}

		if(m_logoTimer.getTicks() > 4000 && m_pFadescreen->isFadingIn()) {
			m_pFadescreen->startFadeOut(10/frameRate);
		} else if(m_pFadescreen->isFadingOut() && m_pFadescreen->finishedFading()) {
			m_currArea = atMain;
			m_pFadescreen->startFadeIn(10/frameRate);
		}

	}

	void EntryScreen::processMain(SDL_Surface *g_pSurface, unsigned int deltaTime) {
		BasePanel::render(g_pSurface, deltaTime);
		m_pBowserIcon->render(g_pSurface, deltaTime);
		m_pFadescreen->render(g_pSurface, deltaTime);
	}

	void EntryScreen::processCredits(SDL_Surface *g_pSurface, unsigned int deltaTime) {
		if(m_pFadescreen->finishedFading()) {
			m_pRoscaCredits->translate(0, -1);
			m_pBassCredits->translate(0, -1);
			m_pBebeCredits->translate(0, -1);
			m_pGottinCredits->translate(0, -1);
		}

		m_pRoscaCredits->render(g_pSurface, deltaTime);
		m_pBassCredits->render(g_pSurface, deltaTime);
		m_pBebeCredits->render(g_pSurface, deltaTime);
		m_pGottinCredits->render(g_pSurface, deltaTime);
		m_pFadescreen->render(g_pSurface, deltaTime);

		if(m_creditsTimer.getTicks() > 50000) {
			m_currArea = atMain;
		}

	}

	void EntryScreen::processIntro(SDL_Surface *g_pSurface, unsigned int deltaTime) {
		bool isIntroFinal = m_introSubArea >= sceneFadingOut5 && m_introSubArea <= introFinal8;

		if(!isIntroFinal) {
			m_pIntroBackground->render(g_pSurface, deltaTime);
			m_bowserAnimationSet->render(g_pSurface, deltaTime, m_bowserPosition);
			m_pFadingMessage->render(g_pSurface, deltaTime);
			
			/************************************************************************/
			/* Bowser talking instances                                             */
			/************************************************************************/
			bool isBowserTalking = 
				m_introSubArea == bowserTalking2 || 
				m_introSubArea == bowserTalking3 ||
				m_introSubArea == bowserTalking4 ||
				m_introSubArea == bowserTalking5 ||
				m_introSubArea == bowserTalking6 ||
				m_introSubArea == bowserTalking7 ||
				m_introSubArea == snifitTalking2 ||
				m_introSubArea == shyguyTalking5 ||
				m_introSubArea == lakituTalking2 ||
				m_introSubArea == lakituTalking4 ||
				m_introSubArea == magikoopaTalking3;

			if(m_pFadingMessage->isFinished() && isBowserTalking) {
				m_bowserAnimationSet->setCurrentAnimation("Talking");
			} else {
				m_bowserAnimationSet->setCurrentAnimation("Idle");
			}

			/************************************************************************/
			/* Bowser sounds                                                        */
			/************************************************************************/
			bool isBowserGrowaning = m_introSubArea == bowserTalking3 || 
				m_introSubArea == snifitTalking2 ||
				m_introSubArea == shyguyTalking5 ||
				m_introSubArea == lakituTalking2 ||
				m_introSubArea == magikoopaTalking3;

			if(m_pFadingMessage->isFinished() && isBowserGrowaning && m_introTimer.getTicks() > 2500) {
				m_introTimer.start();
				m_pBowserSound->playSound(false);
			}

			/************************************************************************/
			/* Side actors:                                                         */
			/************************************************************************/
			bool isMagikoopaScene = m_introSubArea >= sceneFadingIn  && 
				m_introSubArea <= sceneFadingOut2;
			bool isSnifitScene = m_introSubArea >= sceneFadingIn2 &&  
				m_introSubArea <= sceneFadingOut3;
			bool isShyguyScene = m_introSubArea >= sceneFadingIn3 &&  
				m_introSubArea <= sceneFadingOut4;
			bool isLakituScene = m_introSubArea >= sceneFadingIn4 &&  
				m_introSubArea <= sceneFadingOut5;
			if(isMagikoopaScene) {
				if((m_introSubArea == magikoopaTalking || m_introSubArea == magikoopaTalking2) && m_pFadingMessage->isFinished()) {
					m_pMagikoopaAnimationSet->setCurrentAnimation("Talking");
				} else {
					m_pMagikoopaAnimationSet->setCurrentAnimation("Idle");
				}
				m_pMagikoopaAnimationSet->render(g_pSurface, deltaTime, m_magikoopaPosition);
			} else if(isShyguyScene) {
				if((m_introSubArea == shyguyTalking || m_introSubArea == shyguyTalking3) && m_pFadingMessage->isFinished()) {
					m_pShyguyAnimationSet->setCurrentAnimation("Talking");
				} else {
					m_pShyguyAnimationSet->setCurrentAnimation("Idle");
				}
				m_pShyguyAnimationSet->render(g_pSurface, deltaTime, m_shyguyPosition);
			} else if(isSnifitScene) {
				if(m_introSubArea == snifitTalking && m_pFadingMessage->isFinished()) {
					m_pSnifitAnimationSet->setCurrentAnimation("Talking");
				} else {
					m_pSnifitAnimationSet->setCurrentAnimation("Idle");
				}
				m_pSnifitAnimationSet->render(g_pSurface, deltaTime, m_snifitPosition);
			} else if(isLakituScene) {
				if((m_introSubArea == lakituTalking || m_introSubArea == lakituTalking3) && m_pFadingMessage->isFinished()) {
					m_pLakituAnimationSet->setCurrentAnimation("Talking");
				} else {
					m_pLakituAnimationSet->setCurrentAnimation("Idle");
				}
				m_pLakituAnimationSet->render(g_pSurface, deltaTime, m_lakituPosition);
			}
			
			m_pFadescreen->render(g_pSurface, deltaTime);
		} else {
			m_pFadescreen->render(g_pSurface, deltaTime);
			m_bowserAnimationSet->setCurrentAnimation("Sleeping");
			m_bowserAnimationSet->render(g_pSurface, deltaTime, m_bowserPosition);
			m_pFadingMessage->render(g_pSurface, deltaTime);
		}

		

	

		
		/************************************************************************/
		/* Fades:                                                               */
		/************************************************************************/
		if(m_introSubArea == sceneFadingOut || m_introSubArea == sceneFadingOut2 
			|| m_introSubArea == sceneFadingOut3 || m_introSubArea == sceneFadingOut4
			|| m_introSubArea == sceneFadingOut5) {
			if(m_pFadescreen->isFadingOut() && m_pFadescreen->finishedFading()) {
				m_introSubArea = introSubArea(m_introSubArea + 1);
				processIntroSubArea();
			}
		}
		if(m_introSubArea == sceneFadingIn || m_introSubArea == sceneFadingIn2
			|| m_introSubArea == sceneFadingIn3 || m_introSubArea == sceneFadingIn4
			/*|| m_introSubArea == sceneFadingIn5*/) {
			if(m_pFadescreen->isFadingIn() && m_pFadescreen->finishedFading()) {
				m_introSubArea = introSubArea(m_introSubArea + 1);
				processIntroSubArea();
			}
		}
		
	}
	


	void EntryScreen::processIntroSubArea() {
		switch (m_introSubArea) {
				case bowserTalking:
					setIntroText("Bowser nao consegue dormir...");
				break;
				
				case bowserTalking2:
					setIntroText("Bowser: Vou chamar o Magikoopa.");
				break;

				case bowserTalking3:
					setIntroText("Bowser: Magikooopa!!!!!!");
				break;

				case sceneFadingOut:
				case sceneFadingOut2:
				case sceneFadingOut3:
				case sceneFadingOut4:
				case sceneFadingOut5:
					setIntroText(" ");
					m_pFadescreen->startFadeOut(10/frameRate);
				break;
				
				case sceneFadingIn:
				case sceneFadingIn2:
				case sceneFadingIn3:
				case sceneFadingIn4:
				//case sceneFadingIn5:
					m_pFadescreen->startFadeIn(10/frameRate);
				break;

				case bowserTalking4:
				case bowserTalking5:
				case bowserTalking6:
					setIntroText("Bowser: Me conte uma estoria!");
				break;

				case magikoopaTalking:
					setIntroText("Magikoopa: Era uma vez...");
				break;
				
				case magikoopaTalking2:
					setIntroText("Magikoopa: ... dois irmaos gemeos..");
				break;

				case magikoopaTalking3:
				case snifitTalking2:
				case shyguyTalking5:
				case lakituTalking2:
					setIntroText("Bowser: Aaaaaaaarghh!");
				break;

				case snifitTalking:
					setIntroText("Snifit: Um Koopa Trooper, o Yoshi e o Toad entram num bar ...");
				break;

				case shyguyTalking:
				
					setIntroText("Shyguy: Sprechen sie Deutsch?");
				break;

				case shyguyTalking3:
					setIntroText("Kennen Sie das Mario?");
				break;

				case shyguyTalking2:
					setIntroText("Bowser: ...");
				break;

				case shyguyTalking4:
					setIntroText("Shyguy fala alemao.");
				break;

				case bowserTalking7:
					setIntroText("Bowser: Me conte uma estoria, por favor!!");
				break;

				case lakituTalking:
					setIntroText("Lakitu: So conheco estorias onde o mario e o heroi!");
				break;

				case lakituTalking3:
					setIntroText("Lakitu: Mas, que tal contar ovelhas?");
				break;

				case lakituTalking4:
					setIntroText("Bowser: Hm.. Pode funcionar!");
				break;

				case introFinal:
					
					setIntroText("E Bowser finalmente adormece... e sonha.");
				break;

				case introFinal2:
					setIntroText("E sonha que raptou a princesa...");
				break;

				case introFinal3:
					setIntroText("Mas talvez contar ovelhas nao tenha sido uma boa ideia!");
				break;

				case introFinal4:
					setIntroText("No sonho de Bowser, as ovelhas nao sao mais ovelhas... ");
				break;
				
				case introFinal5:
					setIntroText("Elas se transformaram em Marios...");
				break;

				case introFinal6:
					setIntroText("...que estao vindo resgatar a Princesa!");
				break;

				case introFinal7:
					setIntroText("Nao deixe os Marios passarem.");
				break;
			
				case introFinal8:
					setIntroText("Se eles passarem, o sonho se torna um pesadelo e Bowser acorda!");
				break;


		}
	}

	interaction_t EntryScreen::processKeyboardLogo(const SDL_Event &event) {
		interaction_t interaction;
		interaction.type = noInteraction;

		if( event.type == SDL_KEYDOWN ) { 
			switch( event.key.keysym.sym ) {
				case SDLK_RETURN:
				case SDLK_ESCAPE:
					m_nextArea = atMain;
					if(m_pFadescreen->isFadingIn())
						m_pFadescreen->startFadeOut(10/frameRate);
				break;
			}
		}
		return(interaction);
	}

	interaction_t EntryScreen::processKeyboardMain(const SDL_Event & event) {
		interaction_t interaction;
		interaction.type = noInteraction;

		if( event.type == SDL_KEYDOWN ) { 
			//Set the proper message surface
			switch( event.key.keysym.sym ) {
				case SDLK_RETURN:
					if(m_bowserIndex >= 0 && m_bowserIndex <= 2) {
						m_nextArea = atIntro;
						m_difficultSelected = m_bowserIndex;
						m_creditsTimer.start();
						if(m_pFadescreen->isFadingIn())
							m_pFadescreen->startFadeOut(10/frameRate);
					}
					else if(m_bowserIndex == 3) {
						m_nextArea = atCredits;
						m_creditsTimer.start();
						if(m_pFadescreen->isFadingIn())
							m_pFadescreen->startFadeOut(10/frameRate);
					}
				break;
				case SDLK_UP:
					moveUpBowserIcon();
				break;
				case SDLK_DOWN:
					moveDownBowserIcon();
				break;
				
				case SDLK_ESCAPE:
					interaction.type = gameExit;
				break;
			}
		}

		return(interaction);
	}

	interaction_t EntryScreen::processKeyboardCredits(const SDL_Event & event) {
		interaction_t interaction;
		interaction.type = noInteraction;
		if( event.type == SDL_KEYDOWN ) { 
			switch( event.key.keysym.sym ) {
				case SDLK_RETURN:
				case SDLK_ESCAPE:
					m_nextArea = atMain;
					m_pFadescreen->startFadeOut(10/frameRate);
				break;
			}
		}
		return(interaction);
	}

	interaction_t EntryScreen::processKeyboardIntro(const SDL_Event &event) {
		interaction_t interaction;
		interaction.type = noInteraction;

		if( event.type == SDL_KEYDOWN ) { 
			//Set the proper message surface
			switch( event.key.keysym.sym ) {
				case SDLK_ESCAPE:
					interaction.type = advanceToGame;
					interaction.value = m_difficultSelected;
					if(!m_pFadescreen->isFadingOut()) {
						m_pFadescreen->startFadeOut(10/frameRate);
					}
					return(interaction);
				break;

				case SDLK_RETURN:
					if(m_introSubArea == introFinalFinal) {
						interaction.type = advanceToGame;
						interaction.value = m_difficultSelected;
						return(interaction);
					}
					if(!m_pFadingMessage->isFinished()) {
						m_pFadingMessage->finishFading();
					} else {
						m_lastSubArea = m_introSubArea;
						m_introSubArea = introSubArea(m_introSubArea + 1);
						processIntroSubArea();
						
					}
				break;
				

			}
		}

		return(interaction);
	}

	interaction_t EntryScreen::processKeyboard(const SDL_Event &event) {
		
		interaction_t interaction;
		interaction.type = noInteraction;

		switch (m_currArea) {
			case atLogo:
				return processKeyboardLogo(event);
			break;
			
			case atMain:
				return processKeyboardMain(event);
			break;

			case atCredits:
				return processKeyboardCredits(event);
			break;

			case atIntro:
				return processKeyboardIntro(event);
			break;
			
		}

		return(interaction);
	}

	interaction_t EntryScreen::processMouse(const SDL_Event &event) {
		interaction_t interaction;
		interaction.type = noInteraction;

		switch (m_currArea) {
			case atMain:
				if(event.type == SDL_MOUSEMOTION) { 
					
				} else if (event.type == SDL_MOUSEBUTTONDOWN) {
					
				}
			break;
		}

		return(interaction);
	}

	void EntryScreen::moveDownBowserIcon() {
		if(m_pBowserIcon != NULL && m_bowserIndex < 3) {
			m_pBowserIcon->setPosition(m_pBowserIcon->getPosition() + Coord2D(0, 0.058593*screenHeight));
			++m_bowserIndex;
			m_pFireSound->playSound(false);
		}
		
	}

	void EntryScreen::moveUpBowserIcon() {
		if(m_pBowserIcon != NULL && m_bowserIndex > 0) {
			m_pBowserIcon->setPosition(m_pBowserIcon->getPosition() - Coord2D(0, 0.058593*screenHeight));
			--m_bowserIndex;
			m_pFireSound->playSound(false);
		}
		
	}

	
	/************************************************************************/
	/* ctors and dtors                                                      */
	/************************************************************************/
	EntryScreen::EntryScreen() : BasePanel(Coord2D(0,0), Coord2D(0,0)) {
		m_currArea = atLogo;
		m_nextArea = invalidArea;
		m_pFadescreen = new Fadescreen();
		m_pFadescreen->startFadeIn(10/frameRate);
		
		/** Logo Initialization */
		shared_ptr<SDLImage> logoImage = TD_Resources::ResourceManager::loadImage("lacaLogo.png");
		Coord2D logoCenter;
		logoCenter.x = screenWidth/2 - logoImage->getBounds().x/2;
		logoCenter.y = screenHeight/2 - logoImage->getBounds().y/2;
		m_pLacaLogo = new Tile(logoCenter, logoImage->getBounds(), imgTile, logoImage);
		m_logoTimer.start();
		m_pLogoSound = TD_Resources::ResourceManager::loadSound("SFX/sounds/logoSound.wav");
		m_playedIntroSound = false;

		/** Main area initialization */
		m_pImage = TD_Resources::ResourceManager::loadImage(entryScreenBackground);
		shared_ptr<SDLImage> bowserImage = TD_Resources::ResourceManager::loadImage("GUI/Icons/bowser icon.png", Color::PINK);
		m_pBowserIcon = new Tile(iconStartingPos, bowserImage->getBounds(), imgTile, bowserImage);
		m_bowserIndex = 0;
		m_advanceToGame = false;

		/**Credits Initialization */
		Coord2D roscaCenter;
		shared_ptr<SDLImage> roscaImage = TD_Resources::ResourceManager::loadImage("Credits/roscaCredits.jpg");
		roscaCenter.x = screenWidth/2 - roscaImage->getBounds().x/2;
		roscaCenter.y = screenHeight/2 - roscaImage->getBounds().y/2 + 50;
		m_pRoscaCredits = new Tile(roscaCenter, roscaImage->getBounds(), imgTile, roscaImage);

		Coord2D bassCenter;
		shared_ptr<SDLImage> bassImage = TD_Resources::ResourceManager::loadImage("Credits/bassCredits.jpg");
		bassCenter.x = screenWidth/2 - bassImage->getBounds().x/2;
		bassCenter.y = roscaCenter.y + roscaImage->getBounds().y + roscaImage->getBounds().y/2;
		m_pBassCredits = new Tile(bassCenter, bassImage->getBounds(), imgTile, bassImage);

		Coord2D bebeCenter;
		shared_ptr<SDLImage> bebeImage = TD_Resources::ResourceManager::loadImage("Credits/bebeCredits.jpg");
		bebeCenter.x = screenWidth/2 - bebeImage->getBounds().x/2;
		bebeCenter.y = bassCenter.y + bassImage->getBounds().y + bassImage->getBounds().y/2;
		m_pBebeCredits = new Tile(bebeCenter, bebeImage->getBounds(), imgTile, bebeImage);

		Coord2D gottinCenter;
		shared_ptr<SDLImage> gottinImage = TD_Resources::ResourceManager::loadImage("Credits/gottinCredits.jpg");
		gottinCenter.x = screenWidth/2 - gottinImage->getBounds().x/2;
		gottinCenter.y = bebeCenter.y + bebeImage->getBounds().y + + bebeImage->getBounds().y/2; 
		m_pGottinCredits = new Tile(gottinCenter, gottinImage->getBounds(), imgTile, gottinImage);

		m_pFireSound = TD_Resources::ResourceManager::loadSound("SFX/sounds/fire.wav");

		/**Intro initialization.*/
		Color introMessageColor(255, 255, 255, 0); 
		m_pFadingMessage = new FadingMessage(Coord2D(300, 600), "Casa do Bowser ", "Fonts/SuperMarioAlphabet.TTF", 50, introMessageColor, true);

		shared_ptr<SDLImage> introBackgroundImage = TD_Resources::ResourceManager::loadImage("Intro/introscene.png");
		m_pIntroBackground = new Tile(Coord2D(0,0), introBackgroundImage->getBounds(), imgTile, introBackgroundImage);
		m_bowserAnimationSet = TD_Game::AnimationSetFactory::createBowserAnimationSet(Sleeping_Bowser, "Idle");
		m_bowserPosition = Coord2D(630, 300);
		m_introSubArea = bowserWaiting;
		m_pBowserSound = TD_Resources::ResourceManager::loadSound("SFX/sounds/bowser1.wav");
		m_pIntroMusic = TD_Resources::ResourceManager::loadMusic("SFX/music/musica7.mp3");
		m_magikoopaPosition = Coord2D(570, 270);
		m_pMagikoopaAnimationSet = TD_Game::AnimationSetFactory::createBowserAnimationSet(Magikoopa, "Idle");
		m_snifitPosition = Coord2D(574, 273);
		m_pSnifitAnimationSet = TD_Game::AnimationSetFactory::createBowserAnimationSet(Snifit, "Idle");
		m_shyguyPosition = Coord2D(575, 275);
		m_pShyguyAnimationSet = TD_Game::AnimationSetFactory::createBowserAnimationSet(Shyguy, "Idle");
		m_lakituPosition = Coord2D(570, 285);
		m_pLakituAnimationSet = TD_Game::AnimationSetFactory::createBowserAnimationSet(Lakitu, "Idle");
	}

	EntryScreen::EntryScreen(const EntryScreen &rhs) {

	}

	EntryScreen & EntryScreen::operator =(const EntryScreen & rhs) {
		return(*this);
	}
	EntryScreen::~EntryScreen() {
		Utils::safeDelete<Tile>(m_pBowserIcon);
		Utils::safeDelete<Tile>(m_pLacaLogo);
		Utils::safeDelete<Tile>(m_pRoscaCredits);
		Utils::safeDelete<Tile>(m_pBassCredits);
		Utils::safeDelete<Tile>(m_pBebeCredits);
		Utils::safeDelete<Tile>(m_pGottinCredits);
		Utils::safeDelete<Fadescreen>(m_pFadescreen);

		Utils::safeDelete<AnimationSet>(m_bowserAnimationSet);
		Utils::safeDelete<AnimationSet>(m_pMagikoopaAnimationSet);
		Utils::safeDelete<AnimationSet>(m_pSnifitAnimationSet);
		Utils::safeDelete<AnimationSet>(m_pShyguyAnimationSet);
		Utils::safeDelete<AnimationSet>(m_pLakituAnimationSet);
		Utils::safeDelete<FadingMessage>(m_pFadingMessage);
		
	}

	/************************************************************************/
	/* Rendering                                                            */
	/************************************************************************/

	void EntryScreen::render(SDL_Surface *const g_destSurface, unsigned int deltaTime) {

		if(m_nextArea != invalidArea) {
			if(m_pFadescreen->isFadingOut() && m_pFadescreen->finishedFading()) {
				m_currArea = m_nextArea;
				m_nextArea = invalidArea;
				m_pFadescreen->startFadeIn(10/frameRate);
				if(m_currArea == atIntro) {
					m_introTimer.start();
					m_pIntroMusic->playMusic(true);
				}
			}
		}
		if(m_currArea == atLogo) {
			processLogo(g_destSurface, deltaTime);
		} else if(m_currArea == atMain) {
			processMain(g_destSurface, deltaTime);
		} else if(m_currArea == atCredits) {
			processCredits(g_destSurface, deltaTime);
		} else if(m_currArea == atIntro) {
			processIntro(g_destSurface, deltaTime);
		}
		
	}

	interaction_t EntryScreen::processEvent(const SDL_Event &event) {
		
		interaction_t interaction;
		interaction.type = noInteraction;
		
		interaction = processKeyboard(event);
		if(interaction.type == noInteraction) {
			interaction = processMouse(event);
		}
		
		return(interaction);
	}
}